package org.jing.r18.game.venusblood.lagoon;

import org.jing.core.lang.ExceptionHandler;
import org.jing.core.lang.JingException;
import org.jing.core.lang.data.Carrier;
import org.jing.core.lang.data.FileContent;
import org.jing.core.logger.JingLogger;
import org.jing.core.util.DateUtil;
import org.jing.core.util.FileUtil;
import org.jing.core.util.GenericUtil;
import org.jing.r18.game.venusblood.lagoon.dto.Title;
import org.jing.r18.game.venusblood.lang.Const;
import org.jing.r18.game.venusblood.util.Helper;

import java.io.File;
import java.io.FileOutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;

/**
 * Description: <br>
 *
 * @author: bks <br>
 * @createDate: 2025-04-24 <br>
 */
public final class VBLHelper {
    private static final JingLogger LOGGER = JingLogger.getLogger(VBLHelper.class);

    public static final int TITLE_FILTER_MODEL_QUIT = 0;

    public static final int TITLE_FILTER_MODEL_INDEX = 1;

    public static final int TITLE_FILTER_MODEL_ID = 2;

    public static final int TITLE_FILTER_MODEL_NAME = 3;

    public static final int TITLE_FILTER_MODEL_SKILL_ID = 4;

    public static final int TITLE_FILTER_MODEL_SKILL_NAME = 5;

    public static final int SAVE_MODEL_QUIT = 0;

    public static final int SAVE_MODEL_CHANGE_GAME = 1;

    public static final int SAVE_MODEL_CHANGE_UNIT = 2;

    public static final int SAVE_MODEL_CHANGE_ITEM = 3;

    private static final List<Title> TITLES = new ArrayList<>();

    public static int calcGrowthByLevel(int level) {
        return 50 * level * level - 100 * level + 50;
    }

    public static List<Title> getAllTitles() {
        if (TITLES.isEmpty()) {
            File file = new File("files/vbl-" + Const.VERSION_VBL + "/titles.txt");
            try (FileContent fileContent = FileContent.readFile(file)) {
                Carrier titlesC = Carrier.parseJson(fileContent.asString());
                int length = titlesC.getCount("data");
                LOGGER.info("载入称号数据量: [{}]", length);
                for (int i$ = 0; i$ < length; i$++) {
                    Title title = titlesC.getCarrier(i$, "data").serialize(Title.class);
                    TITLES.add(title);
                }
            }
        }
        return TITLES;
    }

    public static Title filterTitle(String titleIndex) {
        List<Title> qryTitles = filterTitles(getAllTitles(), VBLHelper.TITLE_FILTER_MODEL_INDEX, titleIndex);
        ExceptionHandler.publishIfMatch(1 != GenericUtil.count(qryTitles), "称号查询失败");
        return qryTitles.get(0);
    }

    public static List<Title> filterTitles(List<Title> titles, int model, String value) {
        List<Title> result = new ArrayList<>();
        switch (model) {
            case TITLE_FILTER_MODEL_INDEX: {
                for (Title t$ : titles) {
                    if (t$.getIndex() == Integer.parseInt(value)) {
                        result.add(t$);
                        break;
                    }
                }
                break;
            }
            case TITLE_FILTER_MODEL_ID: {
                for (Title t$ : titles) {
                    if (t$.getId().equals(value)) {
                        result.add(t$);
                        break;
                    }
                }
                break;
            }
            case TITLE_FILTER_MODEL_NAME: {
                value = ".*" + value.trim().replaceAll(" ", ".*") + ".*";
                for (Title t$ : titles) {
                    if (t$.getName().matches(value)) {
                        result.add(t$);
                    }
                }
                break;
            }
            case TITLE_FILTER_MODEL_SKILL_ID: {
                for (Title t$ : titles) {
                    if (t$.getSkill().getId().equals(value)) {
                        result.add(t$);
                        break;
                    }
                }
                break;
            }
            case TITLE_FILTER_MODEL_SKILL_NAME: {
                value = ".*" + value.trim().replaceAll(" ", ".*") + ".*";
                for (Title t$ : titles) {
                    if (t$.getSkill().getName().matches(value)) {
                        result.add(t$);
                    }
                }
                break;
            }
            default: break;
        }
        return result;
    }

    public static File getSaveFile(int saveIndex) {
        File file = null;
        for (String dir : Helper.getProjectConfig().getMyDocumentPaths()) {
            file = new File(dir + "/dualtail/VenusBloodLagoon/SaveDatas/userdata" + saveIndex + ".dat");
            if (file.exists()) {
                break;
            }
        }
        ExceptionHandler.publishIfMatch(null == file, "存档不存在");
        return file;
    }

    public static byte[] getSaveBuffer(int saveIndex) {
        File file = getSaveFile(saveIndex);
        try {
            return Files.readAllBytes(file.toPath());
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
    }

    public static void writeSaveBuffer(int saveIndex, byte[] writeBuffer, Carrier saveC) {
        File file = getSaveFile(saveIndex);
        // 备份
        FileUtil.copyFileByChannel(file, new File(file.getAbsolutePath() + ".bak." + DateUtil.getCurrentDateString("yyyyMMddHHmmss")));
        String bodyJson = saveC.asSimpleJson();
        byte[] bodyBuffer = Helper.deflate(bodyJson.getBytes(StandardCharsets.UTF_8));
        try (FileOutputStream fos = new FileOutputStream(file)) {
            // 获取文件的前四个字节，转为整数，表示头部长度
            int headLength = Helper.byteArrayToInt(writeBuffer, 0);
            // 头长度
            fos.write(writeBuffer, 0, 4);
            fos.write(writeBuffer, 4, headLength);
            fos.write(bodyBuffer);
        }
        catch (Throwable t) {
            throw new JingException(t);
        }
        LOGGER.info("覆写完成!");
    }

    public static Carrier getSaveData(byte[] readBuffer) {
        // 获取文件的前四个字节，转为整数，表示头部长度
        int headLength = Helper.byteArrayToInt(readBuffer, 0);
        // 剩余的数据长度
        int restLength = readBuffer.length - headLength - 4;
        // 提取头部数据
        /*byte[] header = new byte[headLength];
        System.arraycopy(array, 4, header, 0, headLength);*/
        // 提取剩余的数据
        byte[] remainingData = new byte[restLength];
        System.arraycopy(readBuffer, headLength + 4, remainingData, 0, restLength);
        // 解码并反序列化数据
        String jsonString = new String(Helper.inflate(remainingData), StandardCharsets.UTF_8);
        return Carrier.parseJson(jsonString);
    }
}
